/*
 * @FileName: [AbstractExcelable.java]
 * 
 * @Package com.bcinfo.iccard.model
 * 
 * 
 * Copyright (c) 2011-2015 BCINFO Technology Limited Com.
 * All rights reserved.
 * 
 * This software is the confidential and proprietary
 * information of BCINFO Technology Limited Company
 * ("Confidential Information"). You shall not disclose
 * such Confidential Information and shall use it only
 * in accordance with the terms of the contract agreement
 * you entered into with RKY.
 * 
 * $Rev$
 * $LastChangedDate$
 * $LastChangedBy$
 * 
 * @category ICCARD
 * 
 * @version 1.1
 * 
 * @author $Author$
 * 
 * Change History:[Formatter: author date description] <br/>
 * 1
 * 2
 * 3
 */

package com.bcinfo.iccard.model;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * 一句话描述 <br/>
 * <p>
 * Description:<br/>
 * <p>
 * 详细描述
 * 
 * <p>
 * For Examples <br/>
 * 
 * <PRE>
 *      TODO 代码使用示例
 * </PRE>
 * <p>
 */
public class AbstractExcelable implements Excelable
{

    // 标题列,在类构造时设置<标题,列名>
    protected Map<String, String> alias      = new LinkedHashMap<String, String>();

    protected Map<String, String> fieldValue = new HashMap<String, String>();

    /*
     * (non-Javadoc)
     * Description: <br/>
     * 
     * @return
     * 
     * @see com.bcinfo.iccard.model.Excelable#getTitles()
     */
    @Override
    public List<String> getTitles()
    {
        String[] tmp = new String[alias.size()];
        alias.keySet().toArray(tmp);
        List<String> ret = new ArrayList<String>();
        for (String t : tmp)
            ret.add(t);
        return ret;
    }

    /*
     * (non-Javadoc)
     * Description: <br/>
     * 
     * @param title
     * 
     * @return
     * 
     * @see com.bcinfo.iccard.model.Excelable#getValue(java.lang.String)
     */
    @Override
    public String getValue(String title)
    {
        String attrName = alias.get(title);
        //
        if (fieldValue.size() == 0)
        {
            fieldValue = getFieldValueMap(this);
        }
        //
        return fieldValue.get(attrName);
    }

    public void resetAlias(Map<String, String> hashmap)
    {
        this.alias = hashmap;
    }

    /**
     * 
     * 取Bean的属性和值对应关系的MAP
     * 
     * @param bean
     * 
     * @return Map
     */
    public static Map<String, String> getFieldValueMap(Object bean)
    {
        Class<?> cls = bean.getClass();
        Map<String, String> valueMap = new HashMap<String, String>();
        // 取出bean里的所有方法
        Method[] methods = cls.getDeclaredMethods();
        Field[] fields = cls.getDeclaredFields();
        for (Field field : fields)
        {
            try
            {
                String fieldType = field.getType().getSimpleName();
                String fieldGetName = parGetName(field.getName());
                if (!checkGetMet(methods, fieldGetName))
                {
                    continue;
                }
                Method fieldGetMet = cls.getMethod(fieldGetName, new Class[]
                {});
                Object fieldVal = fieldGetMet.invoke(bean, new Object[]
                {});
                String result = null;
                if ("Date".equals(fieldType))
                {
                    result = fmtDate((Date) fieldVal);
                }
                else
                {
                    if (null != fieldVal)
                    {
                        result = String.valueOf(fieldVal);
                    }
                }
                valueMap.put(field.getName(), result);
            }
            catch (Exception e)
            {
                continue;
            }
        }
        return valueMap;
    }

    // /**
    // *
    // * 格式化string为Date
    // *
    // * @param datestr
    // *
    // * @return date
    // */
    // private static Date parseDate(String datestr)
    // {
    // if (null == datestr || "".equals(datestr))
    // {
    // return null;
    // }
    // try
    // {
    // String fmtstr = null;
    // if (datestr.indexOf(':') > 0)
    // {
    // fmtstr = "yyyy-MM-dd HH:mm:ss";
    // }
    // else
    // {
    // fmtstr = "yyyy-MM-dd";
    // }
    // SimpleDateFormat sdf = new SimpleDateFormat(fmtstr, Locale.CHINA);
    // return sdf.parse(datestr);
    // }
    // catch (Exception e)
    // {
    // return null;
    // }
    // }

    /**
     * 
     * 日期转化为String
     * 
     * @param date
     * 
     * @return date string
     */
    private static String fmtDate(Date date)
    {
        if (null == date)
        {
            return null;
        }
        try
        {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
            return sdf.format(date);
        }
        catch (Exception e)
        {
            return null;
        }
    }

    // /**
    // *
    // * 判断是否存在某属性的 set方法
    // *
    // * @param methods
    // *
    // * @param fieldSetMet
    // *
    // * @return boolean
    // */
    // private static boolean checkSetMet(Method[] methods, String fieldSetMet)
    // {
    // for (Method met : methods)
    // {
    // if (fieldSetMet.equals(met.getName()))
    // {
    // return true;
    // }
    // }
    // return false;
    // }

    /**
     * 
     * 判断是否存在某属性的 get方法
     * 
     * @param methods
     * 
     * @param fieldGetMet
     * 
     * @return boolean
     */
    private static boolean checkGetMet(Method[] methods, String fieldGetMet)
    {
        for (Method met : methods)
        {
            if (fieldGetMet.equals(met.getName()))
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 
     * 拼接某属性的 get方法
     * 
     * @param fieldName
     * 
     * @return String
     */
    private static String parGetName(String fieldName)
    {
        if (null == fieldName || "".equals(fieldName))
        {
            return null;
        }
        return "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    }
}